package game;

import physics.Circle;

import javax.media.j3d.Transform3D;
import javax.vecmath.Color3f;
import javax.vecmath.Point2d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector2f;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.HashMap;
import java.util.Hashtable;

public class CueBall extends Circle implements MouseListener, MouseMotionListener {

    public static enum State {
        NORMAL,
        SCRATCH
    }

    public State state;

    public CueBall() {
        super(1f, 0, 0, 0, 0, 0, 0, .0243f, new Color3f(1,1,1), new Color3f(1,1,1));
    }

    /**
     * Set the state of the cue ball. Either normal or scratch.
     * @param state State to set.
     */
    public void setState(State state) {
        this.state = state;
        switch (state) {
            case SCRATCH:
                this.addMouseListener();
                try {
                    // move the mouse to scratch area
                    Robot r = new Robot();
                    Point canvasLocation = App.canvas3D.getLocationOnScreen();
                    r.mouseMove(canvasLocation.x + App.canvas3D.getWidth() / 4, canvasLocation.y + App.canvas3D.getHeight() / 2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    /**
     * Strike the ball with a particular velocity
     * @param velocity New velocity
     */
    public void strike(Vector2f velocity) {
        this.velocity = velocity;
    }

    /**
     * Get the pixel location of the ball
     * @return 2d point with x/y in pixels
     */
    public Point2d getPixelLocation() {
        Point3d origin = new Point3d(position.x, position.y, 0);
        Transform3D coordTr = new Transform3D();
        App.canvas3D.getVworldToImagePlate(coordTr);
        coordTr.transform(origin);
        Point2d pixelPoint = new Point2d();
        App.canvas3D.getPixelLocationFromImagePlate(new Point3d(origin.x, origin.y, 0), pixelPoint);
        return pixelPoint;
    }

    /**
     * Starts the mouse listener
     */
    public void addMouseListener() {
        App.addMouseListener(this, this);
    }

    /**
     * Stops the mouse listener.
     */
    public void removeMouseListener() {
        App.removeMouseListener(this, this);
    }

    /**
     * Handle mouse movement. Update/clamp position.
     * @param mouseEvent Mouse move event
     */
    public void mouseMoved(MouseEvent mouseEvent) {
        moveBall(new Point(mouseEvent.getX(), mouseEvent.getY()));
    }

    public void moveBall(Point pixelLocation) {
        Point3d location = new Point3d();
        App.canvas3D.getPixelLocationInImagePlate(pixelLocation.x, pixelLocation.y, location);
        Transform3D coordTr = new Transform3D();
        App.canvas3D.getImagePlateToVworld(coordTr);
        coordTr.transform(location);
        this.position = new Vector2f((float)location.x, (float)location.y);
        App.table.restrictCueBallPosition(this);
        this.updateTransformGroup();
    }

    /**
     * Handle mouse released.
     * @param mouseEvent
     */
    public void mouseReleased(MouseEvent mouseEvent) {
        this.removeMouseListener();
        App.setState(App.State.PLAY);
    }

    public void mousePressed(MouseEvent mouseEvent) { }
    public void mouseEntered(MouseEvent mouseEvent) { }
    public void mouseExited(MouseEvent mouseEvent) { }
    public void mouseDragged(MouseEvent mouseEvent) { }
    public void mouseClicked(MouseEvent mouseEvent) { }

}
